package br.com.usapre.faces;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.model.SelectItem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import br.com.bean.ItemExtrato;
import br.com.business.CartaoBusiness;
import br.com.business.CreditoCargaBusiness;
import br.com.business.DebitoConsumoBusiness;
import br.com.business.SaldoCartaoUsuarioBusiness;
import br.com.businesssql.MovimentacaoGCardBusiness;
import br.com.data.Cartao;
import br.com.data.CreditoCarga;
import br.com.data.DebitoConsumo;
import br.com.datasql.MovimentacaoGCard;
import br.com.login.faces.SessionUsaPreBean;
import br.com.utilidades.faces.SimpleMessageBean;

/**
 * @version 1.0.0
 * @since Fevereiro,28 2013
 * @author Eduardo Francisco Barbosa
 */
@Component
@Scope("session")
public class HomeGerenciaBean extends SimpleMessageBean implements Serializable {

    private static final long serialVersionUID = -4160338452932184550L;

    private SessionUsaPreBean sessionUsaPreBean;

    private double recargas;
    private double consumos;

    private CartaoBusiness cartaoBusinessImpl;
    private CreditoCargaBusiness creditoCargaBusinessImpl;
    private DebitoConsumoBusiness debitoConsumoBusinessImpl;
    private SaldoCartaoUsuarioBusiness saldoCartaoUsuarioBusinessImpl;

    private MovimentacaoGCardBusiness movimentacaoGCardBusinessImpl;

    private Cartao cartaoSelecionado;

    private List<Cartao> cartoesUsuario;
    private Cartao cartaoSelecionadoBusca;

    private List<CreditoCarga> creditoCargas;
    private List<DebitoConsumo> debitoConsumos;

    private List<ItemExtrato> itemExtrato;

    private List<MovimentacaoGCard> movimentacoes;

    private List<SelectItem> listaMeses;

    private String referenciaEscolhida;
    private Boolean mostrarPeriodo;
    private List<SelectItem> referencias;

    private Date dataIni;
    private Date dataFim;

    private Double saldoDisponivel;

    /**
     * Construtor
     */
    @Autowired
    public HomeGerenciaBean(SessionUsaPreBean sessionUsaPreBean, CartaoBusiness cartaoBusinessImpl,
	    CreditoCargaBusiness creditoCargaBusinessImpl, DebitoConsumoBusiness debitoConsumoBusinessImpl,
	    MovimentacaoGCardBusiness movimentacaoGCardBusinessImpl,
	    SaldoCartaoUsuarioBusiness saldoCartaoUsuarioBusinessImpl) {

	this.sessionUsaPreBean = sessionUsaPreBean;

	this.movimentacaoGCardBusinessImpl = movimentacaoGCardBusinessImpl;
	this.cartaoBusinessImpl = cartaoBusinessImpl;
	this.creditoCargaBusinessImpl = creditoCargaBusinessImpl;
	this.debitoConsumoBusinessImpl = debitoConsumoBusinessImpl;
	this.saldoCartaoUsuarioBusinessImpl = saldoCartaoUsuarioBusinessImpl;

	reset();
    }

    /**
     * reset
     */
    public void reset() {

	mostrarPeriodo = Boolean.FALSE;
	referenciaEscolhida = "1";
	referencias = new ArrayList<SelectItem>();
	referencias.add(new SelectItem(1, "últimos 5 dias"));
	referencias.add(new SelectItem(2, "últimos 15 dias"));
	referencias.add(new SelectItem(3, "últimos 30 dias"));
	referencias.add(new SelectItem(4, "Periodo"));

	Calendar diaFinal = Calendar.getInstance();

	Calendar diaInicial = Calendar.getInstance();
	diaInicial.add(Calendar.DAY_OF_MONTH, -5);

	dataFim = diaFinal.getTime();
	dataIni = diaInicial.getTime();

	buscarCartoesDisponiveis();

	buscarGCard();
    }

    /**
     * buscarSaldo
     */
    public void buscarSaldo() {
	// sessionUsaPreBean.getUsuario().getIdGcard();

	saldoDisponivel = saldoCartaoUsuarioBusinessImpl.buscarSaldoCartaoPorUsuarioGCard(sessionUsaPreBean
		.getUsuario().getIdGcard());
    }

    /**
     * buscarCartoesDisponiveis
     */
    public void buscarCartoesDisponiveis() {

	// busca os cartoes do usuario logado
	cartoesUsuario = cartaoBusinessImpl.buscarCartoesPorUsuario(sessionUsaPreBean.getUsuario());

	if (cartoesUsuario.size() == 1) {
	    cartaoSelecionado = cartoesUsuario.get(0);
	}
	if (cartoesUsuario.size() > 1) {
	    for (Cartao cartao : cartoesUsuario) {
		if (cartao.getAdicional().equals(Boolean.FALSE)) {
		    cartaoSelecionado = cartao;
		}
	    }
	}
	if (cartoesUsuario.size() == 0) {
	    cartaoSelecionado = null;
	    String usuarioNaoTemCartaoVinculado = super.getMensagem("MN_usuario_nao_tem_cartao_vinculado");
	    enviaMensagem(usuarioNaoTemCartaoVinculado, usuarioNaoTemCartaoVinculado);
	}

    }

    /**
     * atualizaReferencia
     */
    public void atualizaReferencia() {
	Calendar diaFinal = Calendar.getInstance();
	Calendar diaInicial = Calendar.getInstance();

	if (referenciaEscolhida.equals("4")) {
	    mostrarPeriodo = Boolean.TRUE;

	    diaInicial.set(Calendar.DAY_OF_MONTH, 1);

	    dataFim = diaFinal.getTime();
	    dataIni = diaInicial.getTime();
	}
	if (referenciaEscolhida.equals("3")) {
	    mostrarPeriodo = Boolean.FALSE;

	    diaInicial.add(Calendar.DAY_OF_MONTH, -30);

	    dataFim = diaFinal.getTime();
	    dataIni = diaInicial.getTime();
	}
	if (referenciaEscolhida.equals("2")) {
	    mostrarPeriodo = Boolean.FALSE;

	    diaInicial.add(Calendar.DAY_OF_MONTH, -15);

	    dataFim = diaFinal.getTime();
	    dataIni = diaInicial.getTime();
	}
	if (referenciaEscolhida.equals("1")) {
	    mostrarPeriodo = Boolean.FALSE;

	    diaInicial.add(Calendar.DAY_OF_MONTH, -5);

	    dataFim = diaFinal.getTime();
	    dataIni = diaInicial.getTime();
	}

    }

    /**
     * imprimir
     */
    public void imprimir() {

    }

    /**
     * buscarGCard
     */
    public void buscarGCard() {

	// System.out.println("buscar Chamadox");

	movimentacoes = new ArrayList<MovimentacaoGCard>();

	recargas = 0d;
	consumos = 0d;

	try {

	    if (cartaoSelecionadoBusca == null) {
		movimentacoes = movimentacaoGCardBusinessImpl.listaMovimentacaoGCardPorUsuarioeData(
			sessionUsaPreBean.getUsuario(), dataIni, dataFim);
	    } else {
		movimentacoes = movimentacaoGCardBusinessImpl.listaMovimentacaoGCardPorCartaoeData(
			cartaoSelecionadoBusca, dataIni, dataFim);
	    }

	    // System.out.println(movimentacoes.size());

	} catch (Exception e) {
	    e.printStackTrace();
	    creditoCargas = new ArrayList<CreditoCarga>();
	    debitoConsumos = new ArrayList<DebitoConsumo>();

	    String dadosNaoEncontrado = super.getMensagem("MN_dados_usuario_nao_encontrado");
	    enviaMensagem(dadosNaoEncontrado, dadosNaoEncontrado);
	}

	boolean temp = true;
	for (MovimentacaoGCard mov : movimentacoes) {
	    mov.setBranco(temp);
	    if (temp)
		temp = false;
	    else
		temp = true;
	    if (mov.getValor() > 0) {
		recargas += mov.getValor();
	    } else {
		consumos += mov.getValor();
	    }

	}

	buscarSaldo();

    }

    /**
     * buscarPostGre
     */
    public void buscarPostGre() {

	try {

	    if (cartaoSelecionadoBusca == null) {
		creditoCargas = creditoCargaBusinessImpl.listaCreditoCargaPorUsuarioeData(
			sessionUsaPreBean.getUsuario(), dataIni, dataFim);
		debitoConsumos = debitoConsumoBusinessImpl.listaDebitoConsumoPorUsuarioeData(
			sessionUsaPreBean.getUsuario(), dataIni, dataFim);
	    } else {
		debitoConsumos = debitoConsumoBusinessImpl.listaDebitoConsumoPorCartaoeData(cartaoSelecionadoBusca,
			dataIni, dataFim);
		creditoCargas = creditoCargaBusinessImpl.listaCreditoCargaPorCartaoeData(cartaoSelecionadoBusca,
			dataIni, dataFim);
	    }

	} catch (Exception e) {
	    e.printStackTrace();
	    creditoCargas = new ArrayList<CreditoCarga>();
	    debitoConsumos = new ArrayList<DebitoConsumo>();

	    String dadosNaoEncontrado = super.getMensagem("MN_dados_usuario_nao_encontrado");
	    enviaMensagem(dadosNaoEncontrado, dadosNaoEncontrado);
	}

	consumos = 0;
	recargas = 0;

	itemExtrato = new ArrayList<ItemExtrato>();

	while (!creditoCargas.isEmpty() || !debitoConsumos.isEmpty()) {

	    if (creditoCargas.isEmpty()) {

		ItemExtrato item = new ItemExtrato();
		item.setTipo(ItemExtrato.ITEM_CONSUMO);

		DebitoConsumo debito = debitoConsumos.get(0);
		item.setDebito(debito);
		debitoConsumos.remove(debito);

		int rst = itemExtrato.size() % 2;
		if (rst == 1) {
		    item.setBranco(Boolean.TRUE);
		} else {
		    item.setBranco(Boolean.FALSE);
		}

		consumos += debito.getValor();
		itemExtrato.add(item);

	    } else {
		if (debitoConsumos.isEmpty()) {

		    ItemExtrato item = new ItemExtrato();
		    item.setTipo(ItemExtrato.ITEM_RECARGA);

		    CreditoCarga credito = creditoCargas.get(0);
		    item.setCredito(credito);
		    creditoCargas.remove(credito);

		    int rst = itemExtrato.size() % 2;
		    if (rst == 1) {
			item.setBranco(Boolean.TRUE);
		    } else {
			item.setBranco(Boolean.FALSE);
		    }
		    recargas += credito.getValor();
		    itemExtrato.add(item);

		} else {

		    DebitoConsumo debito = debitoConsumos.get(0);
		    CreditoCarga credito = creditoCargas.get(0);

		    if (credito.getData().after(debito.getData())) {

			ItemExtrato item = new ItemExtrato();
			item.setTipo(ItemExtrato.ITEM_CONSUMO);
			item.setDebito(debito);
			debitoConsumos.remove(debito);

			int rst = itemExtrato.size() % 2;
			if (rst == 1) {
			    item.setBranco(Boolean.TRUE);
			} else {
			    item.setBranco(Boolean.FALSE);
			}
			consumos += debito.getValor();
			itemExtrato.add(item);

		    } else {

			ItemExtrato item = new ItemExtrato();
			item.setTipo(ItemExtrato.ITEM_RECARGA);
			item.setCredito(credito);
			creditoCargas.remove(credito);

			int rst = itemExtrato.size() % 2;
			if (rst == 1) {
			    item.setBranco(Boolean.TRUE);
			} else {
			    item.setBranco(Boolean.FALSE);
			}
			recargas += credito.getValor();
			itemExtrato.add(item);

		    }

		}
	    }

	}

    }

    // SETS AND GETS
    public List<Cartao> getCartoesUsuario() {
	return cartoesUsuario;
    }

    public void setCartoesUsuario(List<Cartao> cartoesUsuario) {
	this.cartoesUsuario = cartoesUsuario;
    }

    public List<SelectItem> getListaMeses() {
	return listaMeses;
    }

    public void setListaMeses(List<SelectItem> listaMeses) {
	this.listaMeses = listaMeses;
    }

    public List<CreditoCarga> getCreditoCargas() {
	return creditoCargas;
    }

    public void setCreditoCargas(List<CreditoCarga> creditoCargas) {
	this.creditoCargas = creditoCargas;
    }

    public Cartao getCartaoSelecionado() {
	return cartaoSelecionado;
    }

    public void setCartaoSelecionado(Cartao cartaoSelecionado) {
	this.cartaoSelecionado = cartaoSelecionado;
    }

    public List<ItemExtrato> getItemExtrato() {
	return itemExtrato;
    }

    public void setItemExtrato(List<ItemExtrato> itemExtrato) {
	this.itemExtrato = itemExtrato;
    }

    public List<DebitoConsumo> getDebitoConsumos() {
	return debitoConsumos;
    }

    public void setDebitoConsumos(List<DebitoConsumo> debitoConsumos) {
	this.debitoConsumos = debitoConsumos;
    }

    public Cartao getCartaoSelecionadoBusca() {
	return cartaoSelecionadoBusca;
    }

    public void setCartaoSelecionadoBusca(Cartao cartaoSelecionadoBusca) {
	this.cartaoSelecionadoBusca = cartaoSelecionadoBusca;
    }

    public String getReferenciaEscolhida() {
	return referenciaEscolhida;
    }

    public void setReferenciaEscolhida(String referenciaEscolhida) {
	this.referenciaEscolhida = referenciaEscolhida;
    }

    public List<SelectItem> getReferencias() {
	return referencias;
    }

    public void setReferencias(List<SelectItem> referencias) {
	this.referencias = referencias;
    }

    public Date getDataIni() {
	return dataIni;
    }

    public void setDataIni(Date dataIni) {
	this.dataIni = dataIni;
    }

    public Date getDataFim() {
	return dataFim;
    }

    public void setDataFim(Date dataFim) {
	this.dataFim = dataFim;
    }

    public Boolean getMostrarPeriodo() {
	return mostrarPeriodo;
    }

    public void setMostrarPeriodo(Boolean mostrarPeriodo) {
	this.mostrarPeriodo = mostrarPeriodo;
    }

    public double getRecargas() {
	return recargas;
    }

    public void setRecargas(double recargas) {
	this.recargas = recargas;
    }

    public double getConsumos() {
	return consumos;
    }

    public void setConsumos(double consumos) {
	this.consumos = consumos;
    }

    public List<MovimentacaoGCard> getMovimentacoes() {
	return movimentacoes;
    }

    public void setMovimentacoes(List<MovimentacaoGCard> movimentacoes) {
	this.movimentacoes = movimentacoes;
    }

    public Double getSaldoDisponivel() {
	return saldoDisponivel;
    }

    public void setSaldoDisponivel(Double saldoDisponivel) {
	this.saldoDisponivel = saldoDisponivel;
    }

    public SaldoCartaoUsuarioBusiness getSaldoCartaoUsuarioBusinessImpl() {
	return saldoCartaoUsuarioBusinessImpl;
    }

    public void setSaldoCartaoUsuarioBusinessImpl(SaldoCartaoUsuarioBusiness saldoCartaoUsuarioBusinessImpl) {
	this.saldoCartaoUsuarioBusinessImpl = saldoCartaoUsuarioBusinessImpl;
    }

}
